<?php

class Account_IndexController extends Zend_Controller_Action
{
	public function indexAction()
	{
		if (Account_Model_Session::hasValidSession()) {
			//TODO: make this configurable
			$this->_redirect('/');
		} else {
			$this->_redirect('/login');
		}
	}

	//TODO: check settings for user registration method (user, invitation, admin) and status (open, closed)
	//TODO: make a method (action) to query the account database for used username or email address (for JS)
	public function registerAction()
	{
		if (Account_Model_Session::hasValidSession()) {
			$this->_redirect('/');
		}


		$flashMessages = array();

		$regClosed = TRUE;
		$activationMethod = 'admin';

		$opts = Kernel::getInstance()->getOptions();
		if (is_array($opts) && is_array($opts['account'])) {
			$accOpts = $opts['account'];
			if (is_array($accOpts['registration'])) {
				$accRegOpts = $accOpts['registration'];
				if (intval($accRegOpts['open']) === 1 && intval($accRegOpts['user']) === 1) {
					$regClosed = FALSE;
				}
			}
			if (is_array($accOpts['activation']) && isset($accOpts['activation']['method'])) {
				$activationMethod = $accOpts['activation']['method'];
			}
		}

		if ($regClosed === TRUE) {
			$this->render('regclosed');
			return;
		}


		$request = $this->getRequest();
		$form    = new Account_Form_Register();

		if ($request->isPost()) {

			if ($form->isValid($request->getPost())) {

				$post = $request->getPost();

				$accInfo = array();
				$accInfo['idname'] = $post['idname'];
				$accInfo['email'] = $post['email'];
				$accInfo['password'] = $post['password'];

				$accReg = new Account_Model_Registration();
				if ($accReg->register($accInfo) === true) {

					Euso_Model_Log::push('account', 'registration.succeeded', NULL,
						array('idname' => $accInfo['idname'], 'email' => $accInfo['email']));

					$fmsg = uniqid();
					$flashMessenger = $this->_helper->FlashMessenger;
					$flashMessenger->setNamespace($fmsg);

					if ($activationMethod == 'email') {
						$flashMessenger->addMessage('Please check your email inbox for account activation procedure.');
						$this->_redirect('/account/activate?fmsg=' . $fmsg);
					} else if ($activationMethod == 'auto') {
						$flashMessenger->addMessage('Registration succeeded. You may login with your account now.');
						$this->_redirect('/login?fmsg=' . $fmsg);
					} else {
						$this->view->message = 'Please wait for the administrator to verify and activate your account.';
					}

					$this->render('regsuccess');
					return;

				} else {
					$logParams = array('idname' => $accInfo['idname'], 'email' => $accInfo['email']);
					$logParamCounter = 1;

					$errCodes = $accReg->getErrorCodes();
					foreach ($errCodes as $errCode) {
						switch ($errCode)
						{
						case Account_Model_Registration::IDNAME_TAKEN:
						case Account_Model_Registration::IDNAME_RESERVED:
							$flashMessages[] = 'Username is not available';
							break;
						case Account_Model_Registration::EMAIL_USED:
							$flashMessages[] = 'Email address already used by an existing account';
							break;
						}
						$logParams['code.'. $logParamCounter] = $errCode;
						$logParamCounter++;
					}

					Euso_Model_Log::push('account', 'registration.failed', NULL, $logParams);
				}
			} else {
				Euso_Model_Log::push('account', 'registration.failed', 'Form has invalid entry(s)',
					array('idname' => $accInfo['idname'], 'email' => $accInfo['email']));
			}
		}

		if ($this->_getParam('fmsg')) {
			$flashMessenger = $this->_helper->FlashMessenger;
			$flashMessenger->setNamespace($this->_getParam('fmsg'));
			$this->view->flashMessages = $flashMessenger->getMessages();
		}
		if (is_array($flashMessages)) {
			if (is_array($this->view->flashMessages)) {
				$this->view->flashMessages = array_unique(array_merge($this->view->flashMessages, $flashMessages));
			} else {
				$this->view->flashMessages = $flashMessages;
			}
		}

		$this->view->form = $form;

		Kernel::getInstance()->setHeadTitle('Register');

		$this->view->singleWidgetPageTitle = 'Register';
		$this->view->singleWidgetPage = TRUE;
	}

	public function activateAction()
	{
		if (Account_Model_Session::hasValidSession()) {
			$this->_redirect('/');
		}


		$flashMessages = array();

		$request = $this->getRequest();

		$actkeyForm = new Account_Form_ActivationKey();
		$akresendForm = new Account_Form_ActkeyResend();

		if ($request->isGet()) {
			// the code from either GET or POST
			$activationKey = $request->getParam('code');

		} else if ($request->isPost()) {

			$post = $request->getPost();

			if (isset($post['identity']) && $akresendForm->isValid($request->getPost())) {

				$identity = $post['identity'];

				$accAct = new Account_Model_Activation();
				if ($accAct->resendActivationKey($identity) === true) {

					Euso_Model_Log::push('account', 'activation.key.resend.succeeded', NULL,
						array('identity' => $identity));

					$akresendForm->reset();
					$flashMessages[] = 'Please check your email inbox for an email contains account activation key';

				} else {
					$logParams = array('identity' => $identity);
					$logParamCounter = 1;

					$errCodes = $accAct->getErrorCodes();
					foreach ($errCodes as $errCode) {
						switch ($errCode) {
						case Account_Model_Activation::ACCOUNT_ACTIVATED:
							$flashMessages[] = 'Your account has been activated';
							break;
						case Account_Model_Activation::ACCOUNT_NOT_FOUND:
							$flashMessages[] = 'Account not found';
							break;
						}
						$logParams['code.'. $logParamCounter] = $errCode;
						$logParamCounter++;
					}

					Euso_Model_Log::push('account', 'activation.key.resend.failed', NULL, $logParams);
				}
			} else {
				Euso_Model_Log::push('account', 'activation.key.resend.failed', 'Form has invalid entry(s)',
					array('identity' => $post['identity']));
			}

			if (isset($post['code']) && $actkeyForm->isValid($post)) {
				$activationKey = $post['code'];
			}
		}


		if (empty($activationKey) === FALSE) {
			$accAct = new Account_Model_Activation();
			if ($accAct->activate($activationKey) === TRUE) {

				Euso_Model_Log::push('account', 'activation.succeeded', NULL,
					array('key' => $activationKey));

				$fmsg = uniqid();
				$flashMessenger = $this->_helper->FlashMessenger;
				$flashMessenger->setNamespace($fmsg);
				$flashMessenger->addMessage('Activation succeeded. You may login now.');

				$this->_redirect('/login?fmsg=' . $fmsg);
			} else {
				$logParams = array('key' => $activationKey);
				$logParamCounter = 1;

				$errCodes = $accAct->getErrorCodes();
				foreach ($errCodes as $errCode) {
					switch ($errCode) {
					case Account_Model_Activation::KEY_NOT_FOUND:
						$flashMessages[] = 'Invalid activation reset key';
						break;
					case Account_Model_Activation::KEY_EXPIRED:
						$actkeyForm->reset();
						$flashMessages[] = 'The activation key has been expired. You may register again.';
						break;
					}
					$logParams['code.'. $logParamCounter] = $errCode;
					$logParamCounter++;
				}

				Euso_Model_Log::push('account', 'activation.failed', NULL, $logParams);
			}
		}


		if ($this->_getParam('fmsg')) {
			$flashMessenger = $this->_helper->FlashMessenger;
			$flashMessenger->setNamespace($this->_getParam('fmsg'));
			$this->view->flashMessages = $flashMessenger->getMessages();
		}
		if (is_array($flashMessages)) {
			if (is_array($this->view->flashMessages)) {
				$this->view->flashMessages = array_unique(array_merge($this->view->flashMessages, $flashMessages));
			} else {
				$this->view->flashMessages = $flashMessages;
			}
		}


		Kernel::getInstance()->setHeadTitle('Account Activation');

		$this->view->actkeyForm = $actkeyForm;
		$this->view->akresendForm = $akresendForm;
	}


	public function pwresetAction()
	{
		if (Account_Model_Session::hasValidSession()) {
			$this->_redirect('/');
		}


		$flashMessages = array();

		$request = $this->getRequest();

		$pwrkeyForm = new Account_Form_PasswordResetKey();
		$pwresetForm = new Account_Form_PasswordReset();

		if ($request->isGet()) {
			// the code from either GET or POST
			$pwresetKey = $request->getParam('code');

		} else if ($request->isPost()) {

			$post = $request->getPost();

			if (isset($post['identity']) && $pwresetForm->isValid($request->getPost())) {

				$identity = $post['identity'];

				$accPwd = new Account_Model_Password();
				if ($accPwd->beginPasswordReset($identity) === true) {

					Euso_Model_Log::push('account', 'pwreset.key.send.succeeded', NULL,
						array('identity' => $identity));

					$pwresetForm->reset();
					$flashMessages[] = 'Please check your email inbox for an email contains password reset procedure';

				} else {
					$logParams = array('identity' => $identity);
					$logParamCounter = 1;

					$errCodes = $accPwd->getErrorCodes();
					foreach ($errCodes as $errCode) {
						switch ($errCode) {
						case Account_Model_Password::ACCOUNT_INACTIVE:
							$flashMessages[] = 'Your account has not activated yet';
							break;
						case Account_Model_Password::ACCOUNT_NOT_FOUND:
							$flashMessages[] = 'Account not found';
							break;
						}
						$logParams['code.'. $logParamCounter] = $errCode;
						$logParamCounter++;
					}

					Euso_Model_Log::push('account', 'pwreset.key.send.failed', NULL, $logParams);
				}
			} else {
				Euso_Model_Log::push('account', 'pwreset.key.send.failed', 'Form has invalid entry(s)',
					array('identity' => $post['identity']));
			}

			if (isset($post['code']) && $pwrkeyForm->isValid($post)) {
				$pwresetKey = $post['code'];
			}
		}


		if (empty($pwresetKey) === FALSE) {
			$accPwd = new Account_Model_Password();
			if ($accPwd->execPasswordReset($pwresetKey) === TRUE) {

				Euso_Model_Log::push('account', 'pwreset.succeeded', NULL,
					array('key' => $pwresetKey));

				$fmsg = uniqid();
				$flashMessenger = $this->_helper->FlashMessenger;
				$flashMessenger->setNamespace($fmsg);
				$flashMessenger->addMessage('Password succesfully reset. Please check your email for your temporary password.');

				$this->_redirect('/login?fmsg=' . $fmsg);

			} else {
				$logParams = array('key' => $pwresetKey);
				$logParamCounter = 1;

				$errCodes = $accPwd->getErrorCodes();
				foreach ($errCodes as $errCode) {
					switch ($errCode) {
					case Account_Model_Password::KEY_NOT_FOUND:
						$flashMessages[] = 'Invalid password reset key';
						break;
					case Account_Model_Password::KEY_EXPIRED:
						$pwrkeyForm->reset();
						$flashMessages[] = 'The password reset key has been expired. You may request another password reset key.';
						break;
					}
					$logParams['code.'. $logParamCounter] = $errCode;
					$logParamCounter++;
				}

				Euso_Model_Log::push('account', 'pwreset.failed', NULL, $logParams);
			}
		}


		if ($this->_getParam('fmsg')) {
			$flashMessenger = $this->_helper->FlashMessenger;
			$flashMessenger->setNamespace($this->_getParam('fmsg'));
			$this->view->flashMessages = $flashMessenger->getMessages();
		}
		if (is_array($flashMessages)) {
			if (is_array($this->view->flashMessages)) {
				$this->view->flashMessages = array_unique(array_merge($this->view->flashMessages, $flashMessages));
			} else {
				$this->view->flashMessages = $flashMessages;
			}
		}


		Kernel::getInstance()->setHeadTitle('Reset Password');

		$this->view->pwresetForm = $pwresetForm;
		$this->view->pwrkeyForm = $pwrkeyForm;
	}


	public function pwchangeAction()
	{
		if (Account_Model_Session::hasValidSession() === FALSE) {
			$this->_redirect('/login');
		}


		$request = $this->getRequest();
		$form    = new Account_Form_PasswordChange();

		if ($request->isPost()) {

			$sessAcc = Account_Model_Session::getAccount();

			if ($form->isValid($request->getPost())) {

				$post = $request->getPost();
	
				$idname = $sessAcc->getIdName();
				$pwdold = $post['password'];
				$pwdnew = $post['password_new'];

				$accPwd = new Account_Model_Password();
				if ($accPwd->changePassword($idname, $pwdold, $pwdnew) === true) {

					Euso_Model_Log::push('account', 'pwchange.succeeded', NULL,
						array('id' => $sessAcc->getId(), 'idname' => $sessAcc->getIdName()));

					//TODO: make this configurable
					Account_Model_Session::endSession(FALSE);

					$fmsg = uniqid();
					$flashMessenger = $this->_helper->FlashMessenger;
					$flashMessenger->setNamespace($fmsg);
					$flashMessenger->addMessage('Password succesfully changed. Please re-login.');

					$this->_redirect('/login?fmsg=' . $fmsg .'&return='. urlencode($_SERVER['REQUEST_URI']));
	
				} else {
					$logParams = array('id' => $sessAcc->getId(), 'idname' => $sessAcc->getIdName());
					$logParamCounter = 1;

					$errCodes = $accPwd->getErrorCodes();
					foreach ($errCodes as $errCode) {
						switch ($errCode) {
						case Account_Model_Password::ACCOUNT_NOT_FOUND:
							$flashMessages[] = 'Account not found';
							break;
						case Account_Model_Password::PASSWORDS_MISMATCH:
							$flashMessages[] = 'Wrong password';
							break;
						}
						$logParams['code.'. $logParamCounter] = $errCode;
						$logParamCounter++;
					}

					Euso_Model_Log::push('account', 'pwchange.failed', NULL, $logParams);
				}
			} else {
				Euso_Model_Log::push('account', 'pwchange.failed', 'Form has invalid entry(s)',
					array('id' => $sessAcc->getId(), 'idname' => $sessAcc->getIdName()));
			}
		}


		if ($this->_getParam('fmsg')) {
			$flashMessenger = $this->_helper->FlashMessenger;
			$flashMessenger->setNamespace($this->_getParam('fmsg'));
			$this->view->flashMessages = $flashMessenger->getMessages();
		}
		if (is_array($flashMessages)) {
			if (is_array($this->view->flashMessages)) {
				$this->view->flashMessages = array_unique(array_merge($this->view->flashMessages, $flashMessages));
			} else {
				$this->view->flashMessages = $flashMessages;
			}
		}


		$this->view->form = $form;

		Kernel::getInstance()->setHeadTitle('Change Password');

		$this->view->singleWidgetPageTitle = 'Change Password';
		$this->view->singleWidgetPage = TRUE;
	}
}
